home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / cvs-1.8 / cvs-1 / cvs-1.8.1 / src / find_names.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  6.0 KB  |  272 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.4 kit.
  7.  * 
  8.  * Find Names
  9.  * 
  10.  * Finds all the pertinent file names, both from the administration and from the
  11.  * repository
  12.  * 
  13.  * Find Dirs
  14.  * 
  15.  * Finds all pertinent sub-directories of the checked out instantiation and the
  16.  * repository (and optionally the attic)
  17.  */
  18.  
  19. #include "cvs.h"
  20.  
  21. static int find_dirs PROTO((char *dir, List * list, int checkadm));
  22. static int find_rcs PROTO((char *dir, List * list));
  23.  
  24. static List *filelist;
  25.  
  26. /*
  27.  * add the key from entry on entries list to the files list
  28.  */
  29. static int add_entries_proc PROTO((Node *, void *));
  30. static int
  31. add_entries_proc (node, closure)
  32.      Node *node;
  33.      void *closure;
  34. {
  35.     Node *fnode;
  36.  
  37.     fnode = getnode ();
  38.     fnode->type = FILES;
  39.     fnode->key = xstrdup (node->key);
  40.     if (addnode (filelist, fnode) != 0)
  41.     freenode (fnode);
  42.     return (0);
  43. }
  44.  
  45. /*
  46.  * compare two files list node (for sort)
  47.  */
  48. static int fsortcmp PROTO ((const Node *, const Node *));
  49. static int
  50. fsortcmp (p, q)
  51.     const Node *p;
  52.     const Node *q;
  53. {
  54.     return (strcmp (p->key, q->key));
  55. }
  56.  
  57. List *
  58. Find_Names (repository, which, aflag, optentries)
  59.     char *repository;
  60.     int which;
  61.     int aflag;
  62.     List **optentries;
  63. {
  64.     List *entries;
  65.     List *files;
  66.     char dir[PATH_MAX];
  67.  
  68.     /* make a list for the files */
  69.     files = filelist = getlist ();
  70.  
  71.     /* look at entries (if necessary) */
  72.     if (which & W_LOCAL)
  73.     {
  74.     /* parse the entries file (if it exists) */
  75.     entries = Entries_Open (aflag);
  76.     if (entries != NULL)
  77.     {
  78.         /* walk the entries file adding elements to the files list */
  79.         (void) walklist (entries, add_entries_proc, NULL);
  80.  
  81.         /* if our caller wanted the entries list, return it; else free it */
  82.         if (optentries != NULL)
  83.         *optentries = entries;
  84.         else
  85.         Entries_Close (entries);
  86.     }
  87.     }
  88.  
  89.     if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT))
  90.     {
  91.     /* search the repository */
  92.     if (find_rcs (repository, files) != 0)
  93.         error (1, errno, "cannot open directory %s", repository);
  94.  
  95.     /* search the attic too */
  96.     if (which & W_ATTIC)
  97.     {
  98.         (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
  99.         (void) find_rcs (dir, files);
  100.     }
  101.     }
  102.  
  103.     /* sort the list into alphabetical order and return it */
  104.     sortlist (files, fsortcmp);
  105.     return (files);
  106. }
  107.  
  108. /*
  109.  * create a list of directories to traverse from the current directory
  110.  */
  111. List *
  112. Find_Directories (repository, which)
  113.     char *repository;
  114.     int which;
  115. {
  116.     List *dirlist;
  117.  
  118.     /* make a list for the directories */
  119.     dirlist = getlist ();
  120.  
  121.     /* find the local ones */
  122.     if (which & W_LOCAL)
  123.     {
  124.     /* look only for CVS controlled sub-directories */
  125.     if (find_dirs (".", dirlist, 1) != 0)
  126.         error (1, errno, "cannot open current directory");
  127.     }
  128.  
  129.     /* look for sub-dirs in the repository */
  130.     if ((which & W_REPOS) && repository)
  131.     {
  132.     /* search the repository */
  133.     if (find_dirs (repository, dirlist, 0) != 0)
  134.         error (1, errno, "cannot open directory %s", repository);
  135.  
  136. #ifdef ATTIC_DIR_SUPPORT        /* XXX - FIXME */
  137.     /* search the attic too */
  138.     if (which & W_ATTIC)
  139.     {
  140.         char dir[PATH_MAX];
  141.  
  142.         (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
  143.         (void) find_dirs (dir, dirlist, 0);
  144.     }
  145. #endif
  146.     }
  147.  
  148.     /* sort the list into alphabetical order and return it */
  149.     sortlist (dirlist, fsortcmp);
  150.     return (dirlist);
  151. }
  152.  
  153. /*
  154.  * Finds all the ,v files in the argument directory, and adds them to the
  155.  * files list.  Returns 0 for success and non-zero if the argument directory
  156.  * cannot be opened.
  157.  */
  158. static int
  159. find_rcs (dir, list)
  160.     char *dir;
  161.     List *list;
  162. {
  163.     Node *p;
  164.     struct dirent *dp;
  165.     DIR *dirp;
  166.  
  167.     /* set up to read the dir */
  168.     if ((dirp = opendir (dir)) == NULL)
  169.     return (1);
  170.  
  171.     /* read the dir, grabbing the ,v files */
  172.     while ((dp = readdir (dirp)) != NULL)
  173.     {
  174.     if (fnmatch (RCSPAT, dp->d_name, 0) == 0) 
  175.     {
  176.         char *comma;
  177.  
  178.         comma = strrchr (dp->d_name, ',');    /* strip the ,v */
  179.         *comma = '\0';
  180.         p = getnode ();
  181.         p->type = FILES;
  182.         p->key = xstrdup (dp->d_name);
  183.         if (addnode (list, p) != 0)
  184.         freenode (p);
  185.     }
  186.     }
  187.     (void) closedir (dirp);
  188.     return (0);
  189. }
  190.  
  191. /*
  192.  * Finds all the subdirectories of the argument dir and adds them to the
  193.  * specified list.  Sub-directories without a CVS administration directory
  194.  * are optionally ignored  Returns 0 for success or 1 on error.
  195.  */
  196. static int
  197. find_dirs (dir, list, checkadm)
  198.     char *dir;
  199.     List *list;
  200.     int checkadm;
  201. {
  202.     Node *p;
  203.     char tmp[PATH_MAX];
  204.     struct dirent *dp;
  205.     DIR *dirp;
  206.  
  207.     /* set up to read the dir */
  208.     if ((dirp = opendir (dir)) == NULL)
  209.     return (1);
  210.  
  211.     /* read the dir, grabbing sub-dirs */
  212.     while ((dp = readdir (dirp)) != NULL)
  213.     {
  214.     if (strcmp (dp->d_name, ".") == 0 ||
  215.         strcmp (dp->d_name, "..") == 0 ||
  216.         strcmp (dp->d_name, CVSATTIC) == 0 ||
  217.         strcmp (dp->d_name, CVSLCK) == 0 ||
  218.         strcmp (dp->d_name, CVSREP) == 0)
  219.         continue;
  220.  
  221. #ifdef DT_DIR
  222.     if (dp->d_type != DT_DIR) 
  223.     {
  224.         if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
  225.         continue;
  226. #endif
  227.         /* don't bother stating ,v files */
  228.         if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
  229.         continue;
  230.  
  231.         sprintf (tmp, "%s/%s", dir, dp->d_name);
  232.         if (!isdir (tmp))
  233.         continue;
  234.  
  235. #ifdef DT_DIR
  236.     }
  237. #endif
  238.  
  239.     /* check for administration directories (if needed) */
  240.     if (checkadm)
  241.     {
  242.         /* blow off symbolic links to dirs in local dir */
  243. #ifdef DT_DIR
  244.         if (dp->d_type != DT_DIR)
  245.         {
  246.         /* we're either unknown or a symlink at this point */
  247.         if (dp->d_type == DT_LNK)
  248.             continue;
  249. #endif
  250.         if (islink (tmp))
  251.             continue;
  252. #ifdef DT_DIR
  253.         }
  254. #endif
  255.  
  256.         /* check for new style */
  257.         (void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
  258.         if (!isdir (tmp))
  259.         continue;
  260.     }
  261.  
  262.     /* put it in the list */
  263.     p = getnode ();
  264.     p->type = DIRS;
  265.     p->key = xstrdup (dp->d_name);
  266.     if (addnode (list, p) != 0)
  267.         freenode (p);
  268.     }
  269.     (void) closedir (dirp);
  270.     return (0);
  271. }
  272.